﻿using System;
using System.IO;
using System.Text;
using DeepZoomPivotConstructor.ErrorAndLoggingInterfaces;

namespace Logging
{
    /// <summary>
    /// Simple file logger. Not exported any longer for MEF as we
    /// have it in the basic libraries now.
    /// </summary>
    public class LoggerFile : IErrorLogger
    {
        /// <summary>
        /// Create a log file from a default set of log files.
        /// </summary>
        private FileInfo _file;
        public LoggerFile(FileInfo f)
        {
            _file = f;
        }

        /// <summary>
        /// Create default logger, with default log file location.
        /// </summary>
        public LoggerFile()
        {
            FileInfo fname = new FileInfo(System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\DeepTalk\\logs\\" + DateTime.Now.ToString("yyyy-MM-dd") + ".log");
            if (!fname.Directory.Exists)
            {
                fname.Directory.Create();
            }
            _file = fname;
        }

        /// <summary>
        /// Write to a file
        /// </summary>
        /// <param name="ID"></param>
        /// <param name="message"></param>
        void LogMessage(StringBuilder msg)
        {
            StreamWriter wr = null;
            lock (this)
            {
                try
                {
                    _file.Refresh();
                    if (_file.Exists)
                    {
                        wr = new StreamWriter(_file.Open(FileMode.Append, FileAccess.Write));
                    }
                    else
                    {
                        _file.Directory.Refresh();
                        if (!_file.Directory.Exists)
                        {
                            _file.Directory.Create();
                        }
                        wr = _file.CreateText();
                    }
                    wr.WriteLine(DateTime.Now.ToString() + " " + msg.ToString());
                }
                finally
                {
                    if (wr != null)
                    {
                        wr.Close();
                    }
                }
            }
        }

        /// <summary>
        /// Log a message with a string ID and a message
        /// </summary>
        /// <param name="ID"></param>
        /// <param name="message"></param>
        public void LogMessage(string ID, string message)
        {
            StringBuilder bld = new StringBuilder();
            bld.Append("(" + ID + ") " + message);
            LogMessage(bld);
        }

        /// <summary>
        /// Log a message with a string ID and a message and an exception dump!
        /// </summary>
        /// <param name="ID"></param>
        /// <param name="message"></param>
        /// <param name="e"></param>
        public void LogMessage(string ID, string message, Exception e)
        {
            StringBuilder bld = new StringBuilder();
            bld.AppendLine("(" + ID + ") " + message + ":");

            DumpException(bld, e);

            LogMessage(bld);
        }

        /// <summary>
        /// Recursively dumps an exception into the builder
        /// </summary>
        /// <param name="bld"></param>
        /// <param name="e"></param>
        private void DumpException(StringBuilder bld, Exception e)
        {
            bld.Append("  ");
            bld.AppendLine(e.Message);

            StringReader rdr = new StringReader(e.StackTrace);

            string l = "";
            while (l != null)
            {
                l = rdr.ReadLine();
                bld.Append("    ");
                bld.AppendLine(l);
            }

            if (e.InnerException != null)
            {
                bld.AppendLine("  Inner Exception: ");
                DumpException(bld, e.InnerException);
            }
        }

        /// <summary>
        /// Start using a file to write out the logger info.
        /// </summary>
        /// <param name="f"></param>
        public void UseFileLogger(FileInfo f)
        {
            _file = f;
        }

        /// <summary>
        /// Moves the log file from one place to the next, and then
        /// also makes sure that we write future messages to that new location.
        /// 
        /// We do the File.Move rather than the FileInfo.Move because in the latter
        /// object itself is changed, and if anyone else is holding onto a copy of this they 
        /// may not realize and this can have a side effect miles from where it was handed in!
        /// </summary>
        /// <param name="baseBuildDir"></param>
        public void SetLogfileLocation(DirectoryInfo baseBuildDir)
        {
            ///
            /// If the old log file doesn't exist for whatever reason, then we
            /// just bail out of here...
            /// 

            _file.Refresh();
            if (!_file.Exists)
                return;

            ///
            /// Now, do the copy over!
            /// 

            baseBuildDir.Refresh();
            if (!baseBuildDir.Exists)
            {
                baseBuildDir.Create();
            }

            FileInfo newfile = null;
            int index = 0;
            do
            {
                string ext = "";
                if (index > 0)
                {
                    ext = index.ToString("000");
                }
                index = index + 1;
                newfile = new FileInfo(baseBuildDir.FullName + "\\" + Path.GetFileNameWithoutExtension(_file.Name) + ext + _file.Extension);
            } while (newfile.Exists);

            File.Move(_file.FullName, newfile.FullName);
            _file = newfile;
#if false
            ///
            /// Setup the log file that we will render to
            /// 

            FileInfo logFile = new FileInfo(Path.GetTempFileName());
            Stream logFileStream = logFile.Create();
            TextWriterTraceListener logFileTracer = new TextWriterTraceListener(logFileStream);
            logFileTracer.TraceOutputOptions = TraceOptions.DateTime | TraceOptions.ThreadId;
            Trace.Listeners.Add(logFileTracer);

            traceProgress.TraceInformation("Starting rendering of URI '{0}'.", _url);



            Trace.Flush();
            Trace.Listeners.Remove(logFileTracer);
            logFileStream.Close();

            if (baseBuildDir == null)
            {
                baseBuildDir = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Deep_Talk_Converter\\logs");
            }
            if (!baseBuildDir.Exists)
            {
                baseBuildDir.Create();
            }
            StringBuilder logname = new StringBuilder();
            logname.Append(baseBuildDir.FullName);
            logname.Append("\\log ");
            logname.AppendFormat("{0:0000}-{1:00}-{2:00}", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
            logname.AppendFormat(" {0:00}-{1:00}-{2:00}", DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second);
            logname.AppendFormat(".txt");
            FileInfo finalLogFile = new FileInfo(logname.ToString());
            logFile.MoveTo(finalLogFile.FullName);
            throw new NotImplementedException();
#endif
        }
    }
}